﻿//-----------------------------------------------------------------------
// <copyright file="Contact.cs" company="Craig Longford (deltawolf7@gmail.com)">
//     Copyright (c) Craig Longford. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Delta.Mercury.Business.User
{
    using System;
    using Delta.Data.DataExpress;
    using Delta.Mercury.Business.Exceptions;

    /// <summary>
    /// Representation of a contact
    /// </summary>
    [Serializable]
    public class Contact : IdentifierBase, IDataServicable
    {
        #region Members
        /// <summary>
        /// Name of the contact
        /// </summary>
        private string contactTypeName;

        /// <summary>
        /// Contact type guid
        /// </summary>
        private Guid contactTypeGuid;

        /// <summary>
        /// Value of the contact
        /// </summary>
        private string contactValue;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the Contact class.
        /// </summary>
        public Contact()
            : this(Guid.Empty, string.Empty, Guid.Empty)
        {
        }

        /// <summary>
        /// Initializes a new instance of the Contact class.
        /// </summary>
        /// <param name="ownerGuid">Owner unique indetifier</param>
        /// <param name="contactValue">Contact value</param>
        /// <param name="contactTypeGuid">Contact type unique identifier</param>
        public Contact(Guid ownerGuid, string contactValue, Guid contactTypeGuid)
            : base()
        {
            this.contactValue = contactValue;
            this.UserGuid = ownerGuid;
            this.contactTypeGuid = contactTypeGuid;

            ContactType contactType = ContactType.Load(this.contactTypeGuid, false);
            if (contactType != null)
            {
                this.contactTypeName = contactType.Name;
            }
            else
            {
                this.contactTypeName = "UNKNOWN";
            }
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the User unique identifier.
        /// </summary>
        public virtual Guid UserGuid { get; set; }

        /// <summary>
        /// Gets or sets the contact type guid.
        /// </summary>
        public virtual Guid ContactTypeGuid
        {
            get
            {
                return this.contactTypeGuid;
            }

            set
            {
                if (value == Guid.Empty)
                {
                    this.contactTypeName = string.Empty;
                }

                this.contactTypeGuid = value;

                ContactType type = ContactType.Load(value, false);
                if (type != null)
                {
                    this.contactTypeName = type.Name;
                }
                else
                {
                    this.contactTypeName = "Unknown";
                }
            }
        }

        /// <summary>
        /// Gets or sets the value of the contact.
        /// </summary>
        public virtual string Value
        {
            get
            {
                return this.contactValue;
            }

            set
            {
                if (value.Length < 1)
                {
                    throw new InvalidLengthException("Contact value must be a minimum of 1 characters.");
                }

                if (value.Length > 30)
                {
                    throw new InvalidLengthException("Contact value must be a maximum of 30 characters.");
                }

                this.contactValue = value.ToLower();
            }
        }

        /// <summary>
        /// Gets the contact type name.
        /// </summary>
        public virtual string Name
        {
            get
            {
                return this.contactTypeName;
            }
        }
        #endregion

        #region Load Method
        /// <summary>
        /// Load contact by unique identifier
        /// </summary>
        /// <param name="guid">Unique identifier</param>
        /// <param name="showDeleted">Show deleted</param>
        /// <returns>Filled contact</returns>
        public static Contact Load(Guid guid, bool showDeleted)
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", guid));
            parameters.Add(new Parameter("Deleted", showDeleted));
            return DataAccess.GetSingle<Contact>("LoadContact", System.Data.CommandType.StoredProcedure, parameters);
        }
        #endregion

        #region Fill Method
        /// <summary>
        /// Fill contact from database
        /// </summary>
        /// <param name="reader">Database data reader</param>
        public virtual void Fill(System.Data.IDataReader reader)
        {
            this.Guid = Helper.ToGuid(reader["Guid"]);
            this.UserGuid = Helper.ToGuid(reader["UserGuid"]);
            this.contactTypeGuid = Helper.ToGuid(reader["ContactTypeGuid"]);
            this.Value = Helper.ToString(reader["Value"]);
            this.contactTypeName = Helper.ToString(reader["Name"]);
        }
        #endregion

        #region Save Method
        /// <summary>
        /// Save contact to database
        /// </summary>
        public virtual void Save()
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", this.Guid));
            parameters.Add(new Parameter("UserGuid", this.UserGuid));
            parameters.Add(new Parameter("ContactTypeGuid", this.contactTypeGuid));
            parameters.Add(new Parameter("Name", this.contactTypeName));
            parameters.Add(new Parameter("Value", this.Value));
            DataAccess.NonQuery("SaveContact", System.Data.CommandType.StoredProcedure, parameters);
        }
        #endregion

        #region Delete Method
        /// <summary>
        /// Delete contact from database
        /// </summary>
        public virtual void Delete()
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", this.Guid));
            DataAccess.NonQuery("DeleteContact", System.Data.CommandType.StoredProcedure, parameters);
        }
        #endregion

        #region Save Parameters
        /// <summary>
        /// Get save parameters
        /// </summary>
        /// <returns>Parameters collection</returns>
        public Parameters GetSaveParameters()
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", this.Guid));
            parameters.Add(new Parameter("UserGuid", this.UserGuid));
            parameters.Add(new Parameter("ContactTypeGuid", this.contactTypeGuid));
            parameters.Add(new Parameter("Name", this.contactTypeName));
            parameters.Add(new Parameter("Value", this.Value));
            return parameters;
        }
        #endregion
    }
}
